﻿using AutoMapper;
using MyToDo.Api.Context.Entity;
using MyToDo.Api.Controllers.Dtos;
using MyToDo.Api.Dtos;
using MyToDo.Api.Service.Parameters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace MyToDo.Api.Service
{
    /// <summary>
    /// 待办事项的实现
    /// </summary>
    public class ToDoService : IToDoService
    {
        private readonly IUnitOfWork unitOfWork;
        private readonly IMapper mapper;
        public ToDoService(IUnitOfWork unitOfWork,IMapper mapper)
        {
            this.unitOfWork = unitOfWork;
            this.mapper = mapper;
        }
        public async Task<ApiResponse> AddAsync(ToDoDto model)
        {
            try
            {
                var todo = mapper.Map<ToDo>(model);
                await unitOfWork.GetRepository<ToDo>().InsertAsync(todo);
                if (await unitOfWork.SaveChangesAsync() > 0)
                    return new ApiResponse(true, todo);
                return new ApiResponse("添加数据失败！");
            }
            catch (Exception ex) {
                return new ApiResponse(ex.Message);
            }
        }
        public async Task<ApiResponse> DeleteAsync(int id)
        {            
            try
            {
                var repository = unitOfWork.GetRepository<ToDo>();
                var todo = await repository.GetFirstOrDefaultAsync(predicate: t => t.Id.Equals(id));
                repository.Delete(todo);
                if (await unitOfWork.SaveChangesAsync() > 0)
                    return new ApiResponse(true,"");
                return new ApiResponse("删除数据失败！");
            }
            catch (Exception ex)
            {
                return new ApiResponse(ex.Message);
            }
        }
        public async Task<ApiResponse> GetAllAsync(QueryParameter query)
        {
            try
            {
                var repository = unitOfWork.GetRepository<ToDo>();
                //var todos = await repository.GetAllAsync();
                var todos = await repository.GetPagedListAsync(predicate:
                    x => string.IsNullOrEmpty(query.Search) ? true : x.Title.Contains(query.Search),
                    pageIndex: query.PageIndex,
                    pageSize: query.PageSize,
                    orderBy: source => source.OrderByDescending(t => t.CreateDate));
                return new ApiResponse(true, todos);
            }
            catch (Exception ex)
            {
                return new ApiResponse(ex.Message);
            }
        }
        public async Task<ApiResponse> GetAllAsync(ToDoParameter query)
        {
            try
            {
                var repository = unitOfWork.GetRepository<ToDo>();
                //var todos = await repository.GetAllAsync();
                var todos = await repository.GetPagedListAsync(predicate:
                    x => (string.IsNullOrEmpty(query.Search) ? true : x.Title.Contains(query.Search))
                      && (query.Status == null ? true : x.Status.Equals(query.Status)),
                    pageIndex: query.PageIndex,
                    pageSize: query.PageSize,
                    orderBy: source => source.OrderByDescending(t => t.CreateDate));
                return new ApiResponse(true, todos);
            }
            catch (Exception ex)
            {
                return new ApiResponse(ex.Message);
            }
        }
        public async Task<ApiResponse> GetSingleAsync(int id)
        {
            try
            {
                var repository = unitOfWork.GetRepository<ToDo>();
                var todo = await repository.GetFirstOrDefaultAsync(predicate: t => t.Id.Equals(id));
                return new ApiResponse(true, todo);
            }
            catch (Exception ex)
            {
                return new ApiResponse(ex.Message);
            }
        }

        public async Task<ApiResponse> Summary()
        {
            try
            {
                var todos = await unitOfWork.GetRepository<ToDo>().GetAllAsync(
                        orderBy:source=>source.OrderByDescending(t=>t.CreateDate)
                    );
                var memos = await unitOfWork.GetRepository<Memo>().GetAllAsync(
                        orderBy: source => source.OrderByDescending(t => t.CreateDate)
                    );
                SummaryDto summary = new SummaryDto();
                summary.Sum = todos.Count;
                summary.CompletedCount = todos.Where(t => t.Status == 1).Count();
                summary.CompletedRatio = (summary.CompletedCount / (double)summary.Sum).ToString("0%");
                summary.MemoCount = memos.Count;
                summary.ToDoList = new System.Collections.ObjectModel.ObservableCollection<ToDoDto>(mapper.Map<List<ToDoDto>>(todos.Where(t => t.Status == 0)));
                summary.MemoList = new System.Collections.ObjectModel.ObservableCollection<MemoDto>(mapper.Map<List<MemoDto>>(memos));
                return new ApiResponse(true, summary);
            }
            catch (Exception ex)
            {
                return new ApiResponse(ex.Message);
            }
        }

        public async Task<ApiResponse> UpdateAsync(ToDoDto model)
        {
            try
            {
                var dbToDo = mapper.Map<ToDo>(model);
                var repository = unitOfWork.GetRepository<ToDo>();
                var todo = await repository.GetFirstOrDefaultAsync(predicate: t => t.Id.Equals(dbToDo.Id));
                todo.Title = dbToDo.Title;
                todo.Content = dbToDo.Content;
                todo.Status = dbToDo.Status;
                todo.UpdateDate = DateTime.Now;
                repository.Update(todo);
                if (await unitOfWork.SaveChangesAsync() > 0)
                    return new ApiResponse(true, todo);
                return new ApiResponse("更新数据失败！");
            }
            catch (Exception ex)
            {
                return new ApiResponse(ex.Message);
            }
        }
    }
}
